import Env from '@/env'
import Tool from '@/libs/tool'
import CryptoJS from 'crypto-js'
import Store from '@/stores/vuex'

const Api = {
	baseUrl: Env.apiDomain,
	apiUrl: Env.apiDomain + Env.apiUri,
	xcxApiUrl: Env.apiDomain + Env.xcxApiUri,
	// 生成图片
	gdImg(w = 300, h = null, fontSize = 1, fontStr = null) {
		const queryObj = { w: w, h: h || w, fontSize: fontSize }
		if (fontStr) {
			queryObj['fontStr'] = fontStr
		}
		return this.apiUrl + '/guest/pub/gd?' + Tool.objectToQueryString(queryObj)
	},
	noImg() {
		return this.apiUrl + '/static/images/noimage.png'
	},
	xcxGuestPost(uri: string, data: object = {}, withLoading: boolean = true) {
		return this.xcxPost(uri, data, withLoading, [], false)
	},
	xcxPost: async function (
		uri: string,
		data: object = {},
		withLoading: boolean = true,
		files: any = [],
		isAuth: boolean = true
	) {
		if (withLoading) {
			uni.showLoading({
				title: '请求中',
				mask: true
			})
		}
		// const isUpload = files.length > 0
		const headers = {
			'Content-Type': '',
			Authorization: undefined
		}
		if (isAuth) {
			const jwt = Store.getters['jwt/getJwt']
			const isJwtExpired = await this.isJwtExpired()
			if (isJwtExpired) {
				await this.xcxWxLogin()
			}
			headers.Authorization = 'Bearer ' + jwt.jwtToken
			data = this.generateXcxFormParams(data)
		}
		headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
		const url = this.xcxApiUrl + uri
		console.log(url)
		return new Promise((resolve, reject) => {
			uni.request({
				method: 'POST',
				timeout: 60000, // ms
				dataType: 'json',
				// responseType: 'arraybuffer',
				sslVerify: !Env.isDev,
				withCredentials: false,
				url: url,
				header: headers,
				data: data,
				success(res: any) {
					if (withLoading) {
						uni.hideLoading()
					}
					// 处理请求成功的情况
					if (res.statusCode === 200 && res.data.code === 200) {
						resolve(res.data)
					} else {
						if (res.statusCode === Env.reLoginStatusCode) {
							Store.commit('jwt/updateJwtToken', '')
						}
						const title = res.message || res.data.message || res.data
						uni.showToast({
							title: title,
							icon: 'none'
						})
						reject(res)
					}
				},
				fail(err: any) {
					if (withLoading) {
						uni.hideLoading()
					}
					// 处理请求失败的情况
					uni.showToast({
						title: err.message || err.data.message,
						icon: 'none'
					})
					reject(err)
				}
			})
		})
	},
	generateXcxFormParams: function (params: any = {}) {
		const _timestamp = Tool.getTimestamp()
		const _nonce =
			_timestamp + '_nonce_' + Math.random() + Math.random() + Math.random() + Math.random()
		const token = Store.getters['jwt/getJwt'].payload.token
		const tokenMd5 = CryptoJS.MD5(token)
		params[tokenMd5] = Store.getters['jwt/getEncryptedMpUserKey']
		params.nonce = _nonce
		params.timestamp = _timestamp
		delete params['sign']
		const keys = Object.keys(params)
		keys.sort()
		const arr = []
		for (const index in keys) {
			const key = keys[index]
			arr[index] = key + '=' + params[key]
		}
		let _sign = arr.join('&')
		_sign = CryptoJS.MD5(_sign).toString()
		params.sign = _sign
		delete params.token
		delete params.key
		delete params[tokenMd5]
		return params
	},
	isJwtExpired() {
		const jwt = Store.getters['jwt/getJwt']
		// console.log(!jwt.jwtToken)
		// console.log(!jwt.payload.token)
		// console.log(jwt.payload.endAt < Tool.getTimestamp())
		return !jwt.jwtToken || !jwt.payload.token || jwt.payload.endAt < Tool.getTimestamp()
	},
	async xcxWxLogin() {
		console.log('xcxWxLogin')
		const token = uni.getStorageSync('token') // 测试用
		if (token) {
			const tokenObj = JSON.parse(token)
			Store.commit('jwt/updateJwtToken', tokenObj.jwtToken)
			Store.commit('jwt/updateEncryptedMpUserKey', tokenObj.encryptedMpUserKey)
			Store.commit('jwt/updateMpUser', tokenObj.mpUser)
			uni.removeStorageSync('token')
		} else {
			const userInfo = await uni.getUserInfo()
			if (userInfo && userInfo.errMsg === 'getUserInfo:ok') {
				const res1 = await uni.login()
				const postData = {
					mp_code: res1.code,
					mp_appid: Env.appid,
					user_info: JSON.stringify(userInfo)
				}
				const res2 = await this.xcxGuestPost('/guest/site/mp-login', postData)
				Store.commit('jwt/updateJwtToken', res2.data.jwtTokenArr.token)
				Store.commit(
					'jwt/updateEncryptedMpUserKey',
					res2.data.jwtTokenArr.encryptedMpUserKey
				)
				Store.commit('jwt/updateMpUser', res2.data.mpUser)
			}
		}
	}
}

export default Api
